package com.laicunba.service.fuiou.impl;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.laicunba.constant.GloabConstant;
import com.laicunba.service.fuiou.FuiouPayForReqService;
import com.laicunba.service.impl.BaseServiceImpl; 
import com.laicunba.util.AssertUtil;
import com.laicunba.util.HttpUtil;
import com.laicunba.util.MD5Util;
import com.laicunba.util.SessionUtil;

@Service
public class FuiouPayForReqServiceImpl extends BaseServiceImpl implements FuiouPayForReqService {
	private static final Logger LOG = Logger.getLogger(FuiouPayForReqServiceImpl.class);

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public PayForReqResponse req(PayForReqParameter param) {
		StringBuilder builder = new StringBuilder();
		builder.append("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?> ");
		builder.append("<payforreq>");
		builder.append("<ver>").append(param.getVer()).append("</ver>");
		builder.append("<merdt>").append(param.getMerdt()).append("</merdt>");
		builder.append("<orderno>").append(param.getOrderno()).append("</orderno>");
		builder.append("<bankno>").append(param.getBankno()).append("</bankno>");
		builder.append("<cityno>").append(param.getCityno()).append("</cityno>");
		builder.append("<branchnm>").append(param.getBranchnm()).append("</branchnm>");
		builder.append("<accntno>").append(param.getAccntno()).append("</accntno>");
		builder.append("<accntnm>").append(param.getAccntnm()).append("</accntnm>");
		builder.append("<amt>").append(param.getAmt()).append("</amt>");
		builder.append("</payforreq>");
		Map p = new HashMap();
		p.put("merid", GloabConstant.FUIOU_MCHNTCD);
		p.put("reqtype", "payforreq");
		p.put("xml", builder.toString());
		p.put("mac", MD5Util.md5Hex(GloabConstant.FUIOU_MCHNTCD + "|" + GloabConstant.FUIOU_MCHNT_KEY + "|payforreq|" + builder.toString()));
		LOG.info(String.format("[rid:%s,tag:FUIOU_PAY_FOR_REQ_POST]\t%s", SessionUtil.RID.get(), p.toString()));
		try {
			String resultXML = HttpUtil.doPost(GloabConstant.FUIOU_PAYFORREQ_PREFIX, p);
			PayForReqResponse response = new PayForReqResponse();
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder;

			docBuilder = factory.newDocumentBuilder();
			Document doc = docBuilder.parse(new ByteArrayInputStream(resultXML.getBytes()));

			response.setRet(getValue(doc, "ret"));
			response.setMemo(getValue(doc, "memo"));
			LOG.info(resultXML);
			return response;
		} catch (IOException e) {
			LOG.error(String.format("[rid:%s,tag:FUIOU_PAY_FOR_REQ_POST_ERROR]", SessionUtil.RID.get()), e);
			AssertUtil.assertFail("FUIOU_PAY_FOR_REQ_POST_ERROR");
		} catch (ParserConfigurationException e) {
			LOG.error(String.format("[rid:%s,tag:FUIOU_RESULT_XML_ERROR1]", SessionUtil.RID.get()), e);
		} catch (SAXException e) {
			LOG.error(String.format("[rid:%s,tag:FUIOU_RESULT_XML_ERROR2]", SessionUtil.RID.get()), e);
		}catch (Exception e) {
			LOG.error(String.format("[rid:%s,tag:FUIOU_RESULT_XML_ERROR3]", SessionUtil.RID.get()), e);
		}
		return null;
	}

	private String getValue(Document doc, String tagName) {
		NodeList nodeList = doc.getElementsByTagName(tagName);
		if (nodeList == null || nodeList.getLength() == 0) {
			return null;
		}
		Element e = (Element) nodeList.item(0);
		return e.getTextContent();
	}
}
